import axios from 'axios';
import crypto from 'crypto';
import config from '../config/index.js';
import { BusinessError } from '../middleware/errorHandler.js';

// 验证码存储（生产环境建议使用Redis）
const verificationCodes = new Map();

// 生成验证码
export const generateVerificationCode = () => {
  return Math.floor(100000 + Math.random() * 900000).toString();
};

// 存储验证码
export const storeVerificationCode = (phone, code, expiresIn = 5 * 60 * 1000) => {
  const expiresAt = Date.now() + expiresIn;
  verificationCodes.set(phone, {
    code,
    expiresAt,
    attempts: 0
  });
  
  // 自动清理过期验证码
  setTimeout(() => {
    verificationCodes.delete(phone);
  }, expiresIn);
};

// 验证验证码
export const verifyCode = (phone, inputCode) => {
  const stored = verificationCodes.get(phone);
  
  if (!stored) {
    throw new BusinessError('验证码不存在或已过期');
  }
  
  if (Date.now() > stored.expiresAt) {
    verificationCodes.delete(phone);
    throw new BusinessError('验证码已过期');
  }
  
  stored.attempts += 1;
  
  if (stored.attempts > 3) {
    verificationCodes.delete(phone);
    throw new BusinessError('验证码尝试次数过多');
  }
  
  if (stored.code !== inputCode) {
    throw new BusinessError('验证码错误');
  }
  
  // 验证成功，删除验证码
  verificationCodes.delete(phone);
  return true;
};

// 阿里云短信发送
const sendAliyunSMS = async (phone, code) => {
  const accessKeyId = config.sms.accessKeyId;
  const accessKeySecret = config.sms.accessKeySecret;
  const signName = config.sms.signName;
  const templateCode = config.sms.templateCode;
  
  if (!accessKeyId || !accessKeySecret) {
    throw new BusinessError('短信服务配置错误');
  }
  
  const params = {
    Action: 'SendSms',
    Version: '2017-05-25',
    RegionId: 'cn-hangzhou',
    PhoneNumbers: phone,
    SignName: signName,
    TemplateCode: templateCode,
    TemplateParam: JSON.stringify({ code }),
    Format: 'JSON',
    Timestamp: new Date().toISOString(),
    SignatureMethod: 'HMAC-SHA1',
    SignatureVersion: '1.0',
    SignatureNonce: Math.random().toString(36).substring(2),
    AccessKeyId: accessKeyId
  };
  
  // 生成签名
  const sortedParams = Object.keys(params)
    .sort()
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    .join('&');
  
  const stringToSign = `POST&${encodeURIComponent('/')}&${encodeURIComponent(sortedParams)}`;
  const signature = crypto
    .createHmac('sha1', accessKeySecret + '&')
    .update(stringToSign)
    .digest('base64');
  
  params.Signature = signature;
  
  try {
    const response = await axios.post('https://dysmsapi.aliyuncs.com/', null, {
      params,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    });
    
    if (response.data.Code === 'OK') {
      return {
        success: true,
        requestId: response.data.RequestId
      };
    } else {
      throw new BusinessError(`短信发送失败: ${response.data.Message}`);
    }
  } catch (error) {
    if (error instanceof BusinessError) {
      throw error;
    }
    throw new BusinessError('短信发送服务异常');
  }
};

// 腾讯云短信发送（示例实现）
const sendTencentSMS = async (phone, code) => {
  // 这里是腾讯云短信的实现示例
  // 实际使用时需要安装腾讯云SDK并配置相关参数
  throw new BusinessError('腾讯云短信服务暂未实现');
};

// 发送验证码短信
export const sendVerificationSMS = async (phone, code = null) => {
  // 验证手机号格式
  const phoneRegex = /^1[3-9]\d{9}$/;
  if (!phoneRegex.test(phone)) {
    throw new BusinessError('手机号格式不正确');
  }
  
  // 生成验证码
  if (!code) {
    code = generateVerificationCode();
  }
  
  // 存储验证码
  storeVerificationCode(phone, code);
  
  try {
    let result;
    
    // 根据配置选择短信服务商
    switch (config.sms.provider) {
      case 'aliyun':
        result = await sendAliyunSMS(phone, code);
        break;
      case 'tencent':
        result = await sendTencentSMS(phone, code);
        break;
      default:
        throw new BusinessError('不支持的短信服务商');
    }
    
    console.log(`短信发送成功: ${phone} -> ${code}`);
    return result;
  } catch (error) {
    // 发送失败时删除存储的验证码
    verificationCodes.delete(phone);
    throw error;
  }
};

// 开发环境模拟短信发送
export const sendMockSMS = async (phone, code = null) => {
  if (!code) {
    code = generateVerificationCode();
  }
  
  storeVerificationCode(phone, code);
  
  console.log(`[模拟短信] 手机号: ${phone}, 验证码: ${code}`);
  
  return {
    success: true,
    requestId: 'mock_' + Date.now(),
    code: process.env.NODE_ENV === 'development' ? code : undefined
  };
};

// 主要的发送短信函数
export const sendSMS = async (phone, code = null) => {
  // 开发环境使用模拟短信
  if (process.env.NODE_ENV === 'development') {
    return await sendMockSMS(phone, code);
  }
  
  return await sendVerificationSMS(phone, code);
};

// 清理过期验证码（定时任务）
export const cleanupExpiredCodes = () => {
  const now = Date.now();
  for (const [phone, data] of verificationCodes.entries()) {
    if (now > data.expiresAt) {
      verificationCodes.delete(phone);
    }
  }
};

// 每5分钟清理一次过期验证码
setInterval(cleanupExpiredCodes, 5 * 60 * 1000);

export default {
  generateVerificationCode,
  storeVerificationCode,
  verifyCode,
  sendSMS,
  sendVerificationSMS,
  sendMockSMS,
  cleanupExpiredCodes
};
